package com.markhsiu.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * 
 * @author Mark Hsiu
 *
 */
public class NIOServer {

	public static void main(String[] args) {
		try {
			new NIOServer().start();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void start() throws IOException{
		Selector selector = Selector.open();
		InetSocketAddress address = new InetSocketAddress(8080);
		
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		serverSocketChannel.configureBlocking(false);
		serverSocketChannel.socket().bind(address);
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		
		System.out.println(" started at " + address);
		while(!Thread.interrupted()){
			int selectNum = selector.select();
			System.out.println("Select Number is : "+selectNum);
			
			Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
			while (iterator.hasNext()) {
				SelectionKey key =  iterator.next();
				System.out.println(key);
				iterator.remove();
				if(key.isAcceptable()){//第一次客户端连接过来
					System.out.println("acceptable event... ");
					ServerSocketChannel serverChannel = (ServerSocketChannel) key.channel();
					SocketChannel socketChannel = serverChannel.accept();
					socketChannel.configureBlocking(false);
					socketChannel.register(selector, SelectionKey.OP_READ);
					socketChannel.write(ByteBuffer.wrap("Welcome Java...\r\n".getBytes()));
					
				} else if(key.isReadable()){//读取客户端发送信息
					//不处理事件会一直循环
					System.out.println("received read event ");
					
					SocketChannel socketChannel = (SocketChannel) key.channel();
					ByteBuffer buffer = ByteBuffer.allocate(100);
					buffer.put("\r\nFollow you: ".getBytes());
					//可以一次性读完Buffer里所有内容而不会发生阻塞
					socketChannel.read(buffer);
					
					int writeBufferSize = socketChannel.socket().getSendBufferSize();
					System.out.println("send buff size :"+writeBufferSize);
					buffer = ByteBuffer.allocate(writeBufferSize*50 +2);
					for (int i = 0; i < buffer.capacity() -2 ; i++) {//一次性写完5被数据
						buffer.put((byte)('a' + i%25));
					}
					buffer.put("\r\n".getBytes());
					System.out.println(buffer.capacity());
					System.out.println(buffer.position() + "  " + buffer.limit());
					buffer.flip();
					System.out.println(buffer.position() + "  " + buffer.limit());
					int writed = socketChannel.write(buffer);
					System.out.println("writed "+writed);
					if(buffer.hasRemaining()){
						System.out.println("not write finished,remains "+buffer.remaining());
					}
				}
			}
		}
	}
}
